package com.googlecode.lightest.core

abstract class LightestTask implements ITask {
	protected TaskNode config
	protected IPreferences prefs
	protected ITestEnvironment env
	protected ITaskResult parentResult
	protected ITaskResult taskResult
    
    /**
     * Configures the task by simply making member variables available to
     * concrete subclasses. Override this method for different configuration
     * behavior. 
     *
     * @param config
     * @param prefs
     * @param env           the environment in which this task is to be
     *                      performed
     * @param parentResult  the result of performing the parent task. May be
     *                      null if this task has no parent.
     */
    void configure(TaskNode config, IPreferences prefs, ITestEnvironment env,
        ITaskResult parentResult)
    {
		this.config = config
		this.prefs = prefs
		this.env = env
    	this.parentResult = parentResult
    }
	
    String getName() {
        return this.class.name
    }
    
    String getDescription() {
        assert config != null
        
        return config.'@description' ?: ""
    }
    
    String getParams() {
        assert config != null
        
        def params = config.attributes().findAll { k, v ->
            k != 'description'
        }
        
        return params.toString()
    }
    
    /**
     * Concrete subclasses must implement this method, which is wrapped by
     * the perform() method. The result is passed in, so implementing methods
     * may simply populate it without needing to create it or return it.
     * 
     * @param result  the result which will be returned by the outer call to
     *                perform().
     */
    abstract void doPerform(ITaskResult result)
    
    /**
     * Performs the task in an environment, and returns the result. Tasks may
     * choose to use or ignore the results of their parent tasks. This
     * implementation wraps doPerform() so it can safely execute the task and
     * add some behaviors to the result.
     */
    ITaskResult perform() {
        def result = new TaskResult(this, parentResult)
        
        result.setStartTime(System.currentTimeMillis())
        
        try {
            doPerform(result)
        }
        catch (e) {
            result.setMessage("Unexpected exception: ${e.getMessage()}")
            result.setResponseData(LightestUtils.getSanitizedStackTrace(e))
            result.fail()
        }
        
        result.setEndTime(System.currentTimeMillis())
        
        return result
    }    
}
